﻿using System;
using System.Data;
using System.Reflection;
using System.IO;
using OverStore.Runtime.Storage;

namespace OverStore.TutorialAsTest
{
    static class TestHelper
    {
        public static void Prepare()
        {
            var fName = Path.Combine(CurrentExecutionPath, MyMoneyDbName);
            if (File.Exists(fName))
                File.Delete(fName);
            using (var write = File.Open(fName, FileMode.Create))
            using (var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(MyMoneyDbResourceName))
            {
                if (resource == null)
                    throw new InvalidOperationException(String.Format("Resource {0} not found", MyMoneyDbResourceName));
                var buffer = new byte[(int)resource.Length];
                resource.Read(buffer, 0, (int)resource.Length);

                write.Write(buffer, 0, buffer.Length);
                write.Close();
                resource.Close();
            }
        }

        private const string MyMoneyDbResourceName = "OverStore.TutorialAsTest.MyMoney.sdf";

        private static string CurrentExecutionPath
        {
            get
            {
                var path = new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase).LocalPath;
                return Path.GetDirectoryName(path);
            }
        }

        private const string MyMoneyDbName = "MyMoney.sdf";

        public static string MyMoneyConnectionString
        {
            get { return String.Format("Data Source = '{0}'", Path.Combine(CurrentExecutionPath, MyMoneyDbName)); }
        }

        public static T GetValue<T>(this IRecord record, string name)
        {
            object result;
            return record.TryGetValue(name, out result) ? (T)result : default(T);
        }

        public static T GetValue<T>(this IDataRecord record, string name)
        {
            var value = record.GetValue(record.GetOrdinal(name));
            if (value == DBNull.Value)
                value = null;
            return (T)value;
        }

        private static string CreateDbCopyAndBuildConnectionString(string dbFileName)
        {
            var directory = CurrentExecutionPath;
            var dbFullPath = Path.Combine(directory, dbFileName);
            if (!File.Exists(dbFullPath))
                throw new InvalidOperationException(String.Format("Database file {0} is not found.", dbFileName));
            var rndName = Guid.NewGuid().ToString() + ".sdf";
            var copyFullPath = Path.Combine(directory, rndName);
            File.Copy(dbFullPath, rndName);
            return String.Format("Data Source = '{0}'", copyFullPath);
        }

        public static string CreateMyMoneyCopyAndBuildConnectionString()
        {
            return CreateDbCopyAndBuildConnectionString("MyMoney.sdf");
        }

        public static string CreateTestDbCopyAndBuildConnectionString()
        {
            return CreateDbCopyAndBuildConnectionString("TestDb.sdf");
        }

        public static string CreatePerformanceDbCopyAndBuildConnectionString()
        {
            return CreateDbCopyAndBuildConnectionString("Performance.sdf");
        }
    }
}
